import os
import sys
from PyQt5.Qt import *
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QApplication, QFileDialog, QPushButton, QHBoxLayout, QVBoxLayout, QStyle, QToolBar, \
    QAction, QListWidget, QSlider
import qdarkgraystyle
from PyQt5.QtCore import *

import pandas as pd
import numpy as np
import time
from struct import *
import serial

ser = serial.Serial("COM2")
# "E:/PycharmProjects/warmup_csv_pyseerial_vofa/csv_fund_quotes/q_217022_债券型-混合债_招商产业债券A.csv"


class MyPlayer(QWidget):
    def __init__(self):
        super(MyPlayer, self).__init__()
        self.state = "Play"
        self.playing = ""
        self.init_ui()

    def init_ui(self):
        # 总的布局是vertical的
        vb = QVBoxLayout()
        self.setLayout(vb)
        vb.setAlignment(Qt.AlignCenter)
        font = QFont("Calibri", 14)

        # 从上到下，第一个控件是一个菜单栏，暂时有添加文件和调节播放方式的按钮
        self.toolbar = QToolBar()
        vb.addWidget(self.toolbar)

        self.addfile_action = QAction("+")
        self.toolbar.addAction(self.addfile_action)
        self.addfile_action.setFont(font)
        self.toolbar.addSeparator()

        self.delfile_action = QAction("-")
        self.toolbar.addAction(self.delfile_action)
        self.delfile_action.setFont(font)
        self.toolbar.addSeparator()

        self.playmode_action = QAction("mode")
        self.toolbar.addAction(self.playmode_action)
        self.playmode_action.setFont(font)

        # 第二个控件是播放列表
        self.playlist = QListWidget()
        vb.addWidget(self.playlist)

        # 第三个控件为slider
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, 1001)
        vb.addWidget(self.slider)

        # 三个button
        hb = QHBoxLayout()
        vb.addLayout(hb)
        # 选上一个文件按钮
        self.btnbackward = QPushButton()
        self.btnbackward.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        hb.addWidget(self.btnbackward)
        # 播放左声道按钮
        self.btnplayL = QPushButton()
        self.btnplayL.setText("Lchn")
        hb.addWidget(self.btnplayL)
        # 播放，暂停按钮
        self.btnplay = QPushButton()
        self.btnplay.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        hb.addWidget(self.btnplay)
        # 播放右声道按钮
        self.btnplayR = QPushButton()
        self.btnplayR.setText("Rchn")
        hb.addWidget(self.btnplayR)
        # 选下一个文件按钮
        self.btnforward = QPushButton()
        self.btnforward.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        hb.addWidget(self.btnforward)

        # 按钮事件
        self.addfile_action.triggered.connect(self.open_file)
        self.btnplay.clicked.connect(self.play_chosen)
        self.btnplayL.clicked.connect(self.play_chosenL)
        self.btnplayR.clicked.connect(self.play_chosenR)

    def open_file(self):
        file_name = QFileDialog()
        file_name.setFileMode(QFileDialog.ExistingFiles)
        names = file_name.getOpenFileNames(self, "Open files", os.getenv("HOME"))
        self.myfile = names[0]
        self.playlist.addItems(self.myfile)
    
    def play_chosen(self):
        if self.state == "Play":
            self.state = "Pause"
            self.btnplay.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
            filepath = self.playlist.currentItem().text()
            if filepath != self.playing:
                self.playing = filepath
                self.thread = Player(filepath)
                self.thread.position_changed.connect(self.set_position)
                self.thread.start()
            else:
                self.thread.resume()

        else:
            self.state = "Play"
            self.btnplay.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            self.thread.pause()

    def play_chosenL(self):
        if self.state == "Play":
            self.state = "Pause"
            self.btnplayL.setText("Lchn")
            filepathl = self.playlist.currentItem().text()
            if filepathl != self.playing:
                self.playing = filepathl
                self.thread = CSVPlayerL(filepathl)
                self.thread.position_changedl.connect(self.set_position)
                self.thread.start()
            else:
                self.thread.resume()

        else:
            self.state = "Play"
            self.btnplayL.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
            self.thread.pause()

    def play_chosenR(self):
        if self.state == "Play":
            self.state = "Pause"
            self.btnplayR.setText("Rchn")
            filepathr = self.playlist.currentItem().text()
            if filepathr != self.playing:
                self.playing = filepathr
                self.thread = CSVPlayerR(filepathr)
                self.thread.position_changedr.connect(self.set_position)
                self.thread.start()
            else:
                self.thread.resume()

        else:
            self.state = "Play"
            self.btnplayR.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
            self.thread.pause()
        # if self.state == "Play":
        #     self.btnplay.setText("||")
        #     path = self.playlist.currentItem().text()
        #     df = pd.read_csv(path, usecols=[2, 3, 4])
        #     mat = np.array(df)
        #     ser = serial.Serial("COM2")
        #
        #     for i in range(len(mat)):
        #         data = pack("fffBBBB", *mat[i], 0x00, 0x00, 0x80, 0x7F)
        #         ser.write(data)
        #         time.sleep(0.1)
        #     ser.close()

    def set_position(self, val):
        self.slider.setValue(val)


class Player(QThread):
    position_changed = pyqtSignal(int)

    def __init__(self, path):
        super(Player, self).__init__()
        self.isPause = False
        self.cond = QWaitCondition()
        self.mutex = QMutex()
        self.filepath = path

    def pause(self):
        print("pause!")
        self.isPause = True

    def resume(self):
        print("resume!")
        self.isPause = False
        self.cond.wakeAll()

    def run(self):
        self.mutex.lock()
        df = pd.read_csv(self.filepath, usecols=[1, 2])
        mat = np.array(df)

        for i in range(len(mat)):
            # self.mutex.lock()
            if self.isPause:
                self.cond.wait(self.mutex)
            data = pack("ffBBBB", *mat[i], 0x00, 0x00, 0x80, 0x7F)
            ser.write(data)
            self.position_changed.emit(i)
            time.sleep(0.1)
            # self.mutex.unlock()
        self.mutex.unlock()
        ser.close()

class CSVPlayerL(QThread):
    position_changedl = pyqtSignal(int)

    def __init__(self, pathl):
        super(CSVPlayerL, self).__init__()
        self.isPausel = False
        self.condl = QWaitCondition()
        self.mutexl = QMutex()
        self.filepathl = pathl

    def pause(self):
        print("pause!")
        self.isPausel = True

    def resume(self):
        print("resume!")
        self.isPausel = False
        self.condl.wakeOne()

    def run(self):
        self.mutexl.lock()
        dfl = pd.read_csv(self.filepathl, usecols=[1])
        matl = np.array(dfl)

        for i in range(len(matl)):
            # self.mutexl.lock()
            if self.isPausel:
                self.condl.wait(self.mutexl)
            datal = pack("fBBBB", *matl[i], 0x00, 0x00, 0x80, 0x7F)
            ser.write(datal)
            self.position_changedl.emit(i)
            time.sleep(0.1)
            # self.mutexl.unlock()
        self.mutexl.unlock()
        ser.close()

class CSVPlayerR(QThread):
    position_changedr = pyqtSignal(int)

    def __init__(self, pathr):
        super(CSVPlayerR, self).__init__()
        self.isPauser = False
        self.condr = QWaitCondition()
        self.mutexr = QMutex()
        self.filepathr = pathr

    def pause(self):
        print("pause!")
        self.isPauser = True

    def resume(self):
        print("resume!")
        self.isPauser = False
        self.condr.wakeOne()

    def run(self):
        self.mutexr.lock()
        dfr = pd.read_csv(self.filepathr, usecols=[2])
        matr = np.array(dfr)

        for i in range(len(matr)):
            # self.mutexr.lock()
            if self.isPauser:
                self.condr.wait(self.mutexr)
            datar = pack("fBBBB", *matr[i], 0x00, 0x00, 0x80, 0x7F)
            ser.write(datar)
            self.position_changedr.emit(i)
            time.sleep(0.1)
            # self.mutexr.unlock()
        self.mutexr.unlock()
        ser.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyleSheet(qdarkgraystyle.load_stylesheet())
    player = MyPlayer()
    player.setGeometry(400, 200, 500, 600)
    player.show()

    sys.exit(app.exec_())
